﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using IPC.Communication.Core;
using IPC.Communication.Core.IMessage;
using IPC.Communication.Core.Net;

namespace IPC.Communication.Profinet.OpenProtocol
{
    public class OpenProtocolNet : NetworkDoubleBase
    {
        public OpenProtocolNet()
        {
            base.ByteTransform = new RegularByteTransform();
        }

        public OpenProtocolNet(string ipAddress, int port)
        {
            IpAddress = ipAddress;
            Port = port;
            base.ByteTransform = new RegularByteTransform();
        }

        protected override INetMessage GetNewNetMessage()
        {
            return new OpenProtocolMessage();
        }

        protected override OperateResult InitializationOnConnect(Socket socket)
        {
            OperateResult<string> operateResult = ReadCustomer(1, 0, 0, 0, null);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            if (operateResult.Content.Substring(4, 4) == "0002")
            {
                return OperateResult.CreateSuccessResult();
            }
            return new OperateResult("Failed:" + operateResult.Content.Substring(4, 4));
        }

        public OperateResult<string> ReadCustomer(int mid, int revison, int stationId, int spindleId, List<string> parameters)
        {
            if (parameters != null)
            {
                parameters = new List<string>();
            }
            OperateResult<byte[]> operateResult = BuildReadCommand(mid, revison, stationId, spindleId, parameters);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult2);
            }
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetString(operateResult2.Content));
        }

        public override string ToString()
        {
            return String.Format("OpenProtocolNet[{0}:{1}]", IpAddress, Port);
        }

        public static OperateResult<byte[]> BuildReadCommand(int mid, int revison, int stationId, int spindleId, List<string> parameters)
        {
            if (mid < 0 || mid > 9999)
            {
                return new OperateResult<byte[]>("Mid must be between 0 - 9999");
            }
            if (revison < 0 || revison > 999)
            {
                return new OperateResult<byte[]>("revison must be between 0 - 999");
            }
            if (stationId < 0 || stationId > 9)
            {
                return new OperateResult<byte[]>("stationId must be between 0 - 9");
            }
            if (spindleId < 0 || spindleId > 99)
            {
                return new OperateResult<byte[]>("spindleId must be between 0 - 99");
            }
            int count = 0;
            if (parameters != null)
            {
                parameters.ForEach(delegate(string m)
            {
                count += m.Length;
            });
            }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append((20 + count).ToString("D4"));
            stringBuilder.Append(mid.ToString("D4"));
            stringBuilder.Append(revison.ToString("D3"));
            stringBuilder.Append('\0');
            stringBuilder.Append(stationId.ToString("D1"));
            stringBuilder.Append(spindleId.ToString("D2"));
            stringBuilder.Append('\0');
            stringBuilder.Append('\0');
            stringBuilder.Append('\0');
            stringBuilder.Append('\0');
            stringBuilder.Append('\0');
            if (parameters != null)
            {
                for (int i = 0; i < parameters.Count; i++)
                {
                    stringBuilder.Append(parameters[i]);
                }
            }
            stringBuilder.Append('\0');
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
        }
    }
}